﻿using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Serialization;
using AviationSimulator.Interfaces;
using AviationSimulator.Properties;

namespace AviationSimulator.DataItems.Mode.Send
{
    public class ManualMode : SendModeBase, IModeDataTableParametrizable, IModeSerializable
    {
        public Package Package { get; set; }
        public DataTable DataTable;

        public ManualMode()
        {
            Package = new Package();

            DataTable = new DataTable();
            DataTable.Columns.Add("Parameter");
            DataTable.Columns.Add("Value");
        }

        public void AddParameter(string parameterName)
        {
            var parameterIsInList = Package.Parameters.Where(parameter =>
                                                             parameter.Name == parameterName).Count() !=
                                                             0;

            if (parameterIsInList)
            {
                MessageBox.Show(Resources.ParameterInListMessage);

                return;
            }

            Package.Parameters.Add(new Parameter
                                       {
                                           Name = parameterName,
                                           Value = " "
                                       });

            var dataRow = DataTable.NewRow();
            dataRow[0] = parameterName;
            dataRow[1] = " ";
            DataTable.Rows.Add(dataRow);
        }

        public void RemoveParameter(int parameterIndex)
        {
            var parameterName = DataTable.Rows[parameterIndex][0].ToString();

            var parameterToRemove = Package.Parameters.First(parameter => parameter.Name == parameterName);
            Package.Parameters.Remove(parameterToRemove);
            DataTable.Rows.RemoveAt(parameterIndex);
        }

        public void EditParametervalue(int parameterIndex, string value)
        {
            try
            {
                var parameterName = DataTable.Rows[parameterIndex][0].ToString();
                Package.Parameters.First(parameter => parameter.Name == parameterName).Value = value;
                DataTable.Rows[parameterIndex][1] = value;
            }
            catch (IndexOutOfRangeException)
            {
                DataTable.Clear();
            }
        }

        public void Serialize(string filePath)
        {
            var modeToSerialize = new ManualModeSerializable
            {
                Address = Address,
                Port = Port,
                Period = Period,
                SendPeriodically = SendPeriodically,
                Package = Package
            };

            var serializer = new XmlSerializer(typeof(ManualModeSerializable));

            using (var streamWriter = new StreamWriter(filePath))
            {
                serializer.Serialize(streamWriter, modeToSerialize);
            }
        }

        public void Deserialize(string filePath)
        {
            var deserializer = new XmlSerializer(typeof(ManualModeSerializable));
            ManualModeSerializable modeToDeserialize;

            try
            {
                using (var streamReader = new StreamReader(filePath))
                {
                    modeToDeserialize = (ManualModeSerializable)deserializer.Deserialize(streamReader);
                }
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show(Resources.CantLoadModeParameters);
                return;
            }

            if (modeToDeserialize == null) return;

            Address = modeToDeserialize.Address;
            Port = modeToDeserialize.Port;
            SendPeriodically = modeToDeserialize.SendPeriodically;
            Period = modeToDeserialize.Period;
            Package = modeToDeserialize.Package;

            UpdateDataTable();
        }

        private void UpdateDataTable()
        {
            DataTable.Clear();

            foreach (var parameter in Package.Parameters)
            {
                var dataRow = DataTable.NewRow();
                dataRow[0] = parameter.Name;
                dataRow[1] = parameter.Value;

                DataTable.Rows.Add(dataRow);
            }
        }
    }
}
